package com.smart.community.property.controller;

import java.util.List;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.dto.property.PropertyCompanyQueryDTO;
import com.smart.community.commons.entity.property.PropertyCompany;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.PageResult;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.property.dto.PropertyCompanyAuditDTO;
import com.smart.community.property.dto.PropertyCompanyDTO;
import com.smart.community.property.service.IPropertyCompanyService;
import com.smart.community.property.vo.PropertyCompanyVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 物业公司管理控制器
 * 
 * 功能说明：
 * 1. 提供物业公司CRUD操作
 * 2. 支持分页查询和条件筛选
 * 3. 支持物业公司审核功能
 * 4. 支持社区分配功能
 * 
 * 权限控制：
 * - 根据"智慧社区微服务架构总览.md"文档，Controller层不进行权限检查
 * - 权限检查由Service层处理，确保数据权限正确过滤
 * - 超级管理员可以查看所有物业公司，普通用户只能查看关联的物业公司
 * 
 * @author Wu.Liang
 * @since 2025-01-29
 */
@Slf4j
@RestController
@RequestMapping("/property/companies")
@RequiredArgsConstructor
@Validated
@Tag(name = "物业公司管理", description = "物业公司相关接口")
public class PropertyCompanyController {
    private final IPropertyCompanyService propertyCompanyService;
    
    /**
     * 查询当前用户的物业公司信息
     * @return 当前用户的物业公司信息
     */
    @GetMapping("/current-user")
    @Operation(summary = "查询当前用户物业公司", description = "查询当前登录用户的物业公司信息")
    public Result<PropertyCompanyVO> getCurrentUserPropertyCompany() throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        Result<PropertyCompanyVO> result = propertyCompanyService.getCurrentUserPropertyCompany();
        log.debug("当前用户ID：{} -- 查询当前用户物业公司信息成功", userId);
        return result;
    }
    
    /**
     * 根据ID查询物业公司详情
     * @param id 物业公司ID
     * @return 物业公司详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "查询物业公司详情", description = "根据ID查询物业公司详细信息")
    public Result<PropertyCompanyVO> getPropertyCompany(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id) throws Exception {
    	Long userId = SecurityUtils.getCurrentUserId();
        log.info("查询物业公司详情，ID：{}，currentUserId：{}", id, userId);
        Result<PropertyCompanyVO> result = propertyCompanyService.getPropertyCompany(id);
        return result;
    }
    
    /**
     * 根据公司编码查询物业公司
     * @param companyCode 公司编码
     * @return 物业公司信息
     */
    @GetMapping("/by-code/{companyCode}")
    @Operation(summary = "根据公司编码查询物业公司", description = "根据公司编码查询物业公司详细信息")
    public Result<PropertyCompanyVO> getPropertyCompanyByCode(
            @Parameter(description = "公司编码") @PathVariable @NotNull String companyCode) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        log.info("根据公司编码查询物业公司，公司编码：{}，currentUserId：{}", companyCode, userId);
        PropertyCompany propertyCompany = propertyCompanyService.getByCompanyCode(companyCode);
        if (propertyCompany == null) {
            return Result.fail("物业公司不存在");
        }
        PropertyCompanyVO vo = convertToVO(propertyCompany);
        return Result.success(vo);
    }
    
    /**
     * 分页查询物业公司列表
     * @param current 当前页码
     * @param size 每页大小
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    @GetMapping
    @Operation(summary = "分页查询物业公司列表", description = "根据条件分页查询物业公司信息")
    public Result<PageResult<PropertyCompanyVO>> getPropertyCompanyList(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "查询条件") @ModelAttribute PropertyCompanyQueryDTO queryDTO) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        queryDTO.setCurrent(current);
        queryDTO.setSize(size);
        Result<PageResult<PropertyCompanyVO>> result = propertyCompanyService.getPropertyCompanyList(queryDTO);
        log.info("分页查询物业公司列表成功，用户ID：{}，返回数据条数：{}", 
            userId, result.getData() != null ? result.getData().getRecords().size() : 0);
        return result;
    }
    
	@ApiLog(logTitle = "更新当前用户物业公司", logType = 2, // 操作日志
			moduleName = "物业管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/current-user")
    @Operation(summary = "更新当前用户物业公司", description = "更新当前登录用户的物业公司信息")
    public Result<Void> updateCurrentUserPropertyCompany(
            @Parameter(description = "物业公司信息") @Valid @RequestBody PropertyCompanyDTO propertyCompanyDTO) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        log.info("用户[{}]更新当前用户物业公司信息：{}", userId, propertyCompanyDTO);
        return propertyCompanyService.updateCurrentUserPropertyCompany(propertyCompanyDTO);
    }
    
	@ApiLog(logTitle = "更新物业公司", logType = 2, // 操作日志
			moduleName = "物业管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{id}")
    @Operation(summary = "更新物业公司", description = "更新物业公司信息")
    public Result<Void> updatePropertyCompany(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id,
            @Parameter(description = "物业公司信息") @Valid @RequestBody PropertyCompanyDTO propertyCompanyDTO) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        log.info("用户[{}]更新物业公司，ID：{}，信息：{}", userId, id, propertyCompanyDTO);
        return propertyCompanyService.updatePropertyCompany(id, propertyCompanyDTO);
    }
    
    /**
     * 获取可分配的社区列表
     * @param id 物业公司ID
     * @param searchKeyword 搜索关键词（可选）
     * @return 可分配的社区列表
     */
    @GetMapping("/{id}/available-communities")
    @Operation(summary = "获取可分配的社区", description = "获取可以分配给指定物业公司的社区列表，支持社区名称搜索")
    public Result<List<Object>> getAvailableCommunities(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id,
            @Parameter(description = "搜索关键词") @RequestParam(required = false) String searchKeyword) throws Exception {
        List<Object> communities = propertyCompanyService.getAvailableCommunities(id, searchKeyword);
        log.info("获取可分配的社区成功，物业公司ID：{}，可分配社区数量：{}", id, communities.size());
        return Result.success(communities);
    }
    
    /**
     * 获取物业公司列表（用于下拉选择）
     * @return 物业公司列表
     */
    @GetMapping("/list")
    @Operation(summary = "获取物业公司列表", description = "获取所有可用的物业公司列表，用于下拉选择")
    public Result<List<PropertyCompanyVO>> getPropertyCompanyList() throws Exception {
        List<PropertyCompanyVO> companies = propertyCompanyService.getPropertyCompanyListForSelect();
        log.info("获取物业公司列表成功，数量：{}", companies.size());
        return Result.success(companies);
    }
    
    /**
     * 获取物业公司详情统计信息
     * @param id 物业公司ID
     * @return 统计信息
     */
    @GetMapping("/{id}/detail-stats")
    @Operation(summary = "获取物业公司详情统计", description = "获取指定物业公司的详细统计信息，包括关联社区数、员工数、服务房户数等")
    public Result<Object> getPropertyCompanyDetailStats(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id) throws Exception {
        Object stats = propertyCompanyService.getPropertyCompanyDetailStats(id);
        log.info("获取物业公司详情统计信息成功，物业公司ID：{}", id);
        return Result.success(stats);
    }

    /**
     * 获取物业公司统计信息
     * @return 统计信息
     */
    @GetMapping("/stats")
    @Operation(summary = "获取物业公司统计", description = "获取物业公司相关统计信息")
    public Result<Object> getPropertyCompanyStats() throws Exception {
        Object stats = new Object();
        log.info("获取物业公司统计信息成功");
        return Result.success(stats);
    }
    
    /**
     * 获取物业公司已分配的社区列表
     * @param id 物业公司ID
     * @param searchKeyword 搜索关键词（可选）
     * @return 社区列表
     */
    @GetMapping("/{id}/assigned-communities")
    @Operation(summary = "获取物业公司已分配的社区", description = "获取指定物业公司已分配的社区列表，支持社区名称搜索")
    public Result<List<Object>> getAssignedCommunities(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id,
            @Parameter(description = "搜索关键词") @RequestParam(required = false) String searchKeyword) throws Exception {
        List<Object> communities = propertyCompanyService.getAssignedCommunities(id, searchKeyword);
        log.info("获取物业公司已分配的社区成功，物业公司ID：{}，社区数量：{}", id, communities.size());
        return Result.success(communities);
    }
    
	@ApiLog(logTitle = "批量删除物业公司", logType = 2, // 操作日志
			moduleName = "物业管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除物业公司", description = "批量删除物业公司信息")
    public Result<Void> batchDeletePropertyCompany(
            @Parameter(description = "物业公司ID列表") @RequestBody @NotNull List<Long> ids) throws Exception {
        for (Long id : ids) {
            propertyCompanyService.deletePropertyCompany(id);
        }
        log.info("批量删除物业公司成功，共删除{}个", ids.size());
        return Result.success();
    }
    
	@ApiLog(logTitle = "删除物业公司", logType = 2, // 操作日志
			moduleName = "物业管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/{id}")
    @Operation(summary = "删除物业公司", description = "删除物业公司信息")
    public Result<Void> deletePropertyCompany(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        Result<Void> result = propertyCompanyService.deletePropertyCompany(id);
        log.info("用户[{}]删除物业公司成功，ID：{}", userId, id);
        return result;
    }
    
    /**
     * 审核物业公司
     * @param id 物业公司ID
     * @param auditDTO 审核信息
     * @return 操作结果
     */
    @ApiLog(logTitle = "审核物业公司", logType = 2, // 操作日志
            moduleName = "物业管理", operationType = ApiLogOperationType.UPDATE)
    @PostMapping("/{id}/audit")
    @Operation(summary = "审核物业公司", description = "审核物业公司申请")
    public Result<Void> auditPropertyCompany(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id,
            @Parameter(description = "审核信息") @Valid @RequestBody PropertyCompanyAuditDTO auditDTO) throws Exception {
        log.info("审核物业公司，ID：{}，审核信息：{}", id, auditDTO);
        Result<Void> result = propertyCompanyService.auditPropertyCompany(id, auditDTO);
        log.info("审核物业公司成功，ID：{}", id);
        return result;
    }
    
    /**
     * 为物业公司分配社区
     * @param id 物业公司ID
     * @param communityIds 社区ID列表
     * @return 操作结果
     */
    @ApiLog(logTitle = "为物业公司分配社区", logType = 2, // 操作日志
            moduleName = "物业管理", operationType = ApiLogOperationType.UPDATE)
    @PostMapping("/{id}/assign-communities")
    @Operation(summary = "为物业公司分配社区", description = "为指定物业公司分配社区")
    public Result<String> assignCommunitiesToPropertyCompany(
            @Parameter(description = "物业公司ID") @PathVariable @NotNull Long id,
            @Parameter(description = "社区ID列表") @Valid @RequestBody List<Long> communityIds) throws Exception {
        log.info("为物业公司分配社区，物业公司ID：{}，社区ID列表：{}", id, communityIds);
        Result<String> result = propertyCompanyService.assignCommunitiesToPropertyCompany(id, communityIds);
        return Result.success(result.getData());
    }
    
    /**
     * 新增物业公司
     * @param propertyCompanyDTO 物业公司信息
     * @return 操作结果
     */
    @ApiLog(logTitle = "新增物业公司", logType = 2, // 操作日志
            moduleName = "物业管理", operationType = ApiLogOperationType.ADD)
    @PostMapping
    @Operation(summary = "新增物业公司", description = "创建新的物业公司信息")
    public Result<Void> createPropertyCompany(
            @Parameter(description = "物业公司信息") @Valid @RequestBody PropertyCompanyDTO propertyCompanyDTO) throws Exception {
        log.info("新增物业公司，信息：{}", propertyCompanyDTO);
        Result<Void> result = propertyCompanyService.createPropertyCompany(propertyCompanyDTO);
        log.info("新增物业公司成功");
        return result;
    }
    
    /**
     * 物业公司注册
     * @param propertyCompanyDTO 物业公司注册信息
     * @return 操作结果
     */
    @PostMapping("/register")
    @Operation(summary = "物业公司注册", description = "物业公司注册申请，注册时状态为待审核")
    public Result<Void> registerPropertyCompany(
            @Parameter(description = "物业公司注册信息") @Valid @RequestBody PropertyCompanyDTO propertyCompanyDTO) throws Exception {
        log.info("物业公司注册申请，信息：{}", propertyCompanyDTO);
        Result<Void> result = propertyCompanyService.registerPropertyCompany(propertyCompanyDTO);
        log.info("物业公司注册申请提交成功");
        return result;
    }
    
    /**
     * 转换为VO对象
     */
    private PropertyCompanyVO convertToVO(PropertyCompany propertyCompany) {
        PropertyCompanyVO vo = new PropertyCompanyVO();
        org.springframework.beans.BeanUtils.copyProperties(propertyCompany, vo);

        // 设置状态名称
        vo.setStatusName(getStatusName(propertyCompany.getStatus()));
        vo.setAuditStatusName(getAuditStatusName(propertyCompany.getAuditStatus()));

        return vo;
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null)
            return "";
        switch (status) {
        case 0:
            return "禁用";
        case 1:
            return "启用";
        default:
            return "未知";
        }
    }

    /**
     * 获取审核状态名称
     */
    private String getAuditStatusName(Integer auditStatus) {
        if (auditStatus == null)
            return "";
        switch (auditStatus) {
        case 0:
            return "待审核";
        case 1:
            return "审核通过";
        case 2:
            return "审核拒绝";
        case 3:
            return "审核拒绝";
        default:
            return "未知";
        }
    }
} 